#include "cef_c_wrapper.h"

#include <string.h>

#include "logger.h"

// #pragma comment(linker, "/subsystem:windows /entry:mainCRTStartup")

cef_browser_view_t *g_browseer;

IPC_Value *on_main_process_message_handler_impl(char *event_name, int call_type, IPC_Value *args) {
    LOG_INFO("event_name %s", event_name);
    LOG_INFO("call_type %d", call_type);
    LOG_INFO("args is NULL %d", args == NULL);

    if (args) {
        int count = args->count;
        for (int i = 0; i < count; i++) {
            IPC_Value *value = ipc_value_get_element(args, i);
            LOG_INFO("value type %d", ipc_value_get_type(value));
            if (ipc_value_get_type(value) == IPC_TYPE_INT) {
                LOG_INFO("value int %d", ipc_value_get_int(value));
            } else if (ipc_value_get_type(value) == IPC_TYPE_STRING) {
                LOG_INFO("value string %s", ipc_value_get_string(value));
            } else if (ipc_value_get_type(value) == IPC_TYPE_DOUBLE) {
                LOG_INFO("value double %f", ipc_value_get_double(value));
            } else if (ipc_value_get_type(value) == IPC_TYPE_BOOL) {
                LOG_INFO("value bool %d", ipc_value_get_bool(value));
            }
        }
    }

    if (strcmp("js_on1", event_name) == 0) {
        // 调用js测试
        IPC_Value *param = _create_ipc_value_string("hello js on1");
        cef_browser_t *browser = g_browseer->get_browser(g_browseer);
        _ipc_main_send(browser, "call_js1", param, 1);
    } else if (strcmp("js_on2", event_name) == 0) {
        IPC_Value *param = _create_ipc_value_list();
        IPC_Value *param1 = _create_ipc_value_int(100);
        IPC_Value *param2 = _create_ipc_value_string("hello world");
        _list_add_element(param, param1);
        _list_add_element(param, param2);
        cef_browser_t *browser = g_browseer->get_browser(g_browseer);
        _ipc_main_send(browser, "call_js2", param, 1);
    } else if (strcmp("js_on3", event_name) == 0) {
        cef_browser_t *browser = g_browseer->get_browser(g_browseer);
        _ipc_main_send(browser, "call_js3", NULL, 1);
    } else if (strcmp("js_on4", event_name) == 0) {
        IPC_Value *param = _create_ipc_value_list();
        IPC_Value *param1 = _create_ipc_value_int(100);
        IPC_Value *param2 = _create_ipc_value_string("hello world");
        _list_add_element(param, param1);
        _list_add_element(param, param2);
        cef_browser_t *browser = g_browseer->get_browser(g_browseer);
        _ipc_main_send(browser, "call_js4", param, 1);
    } else if (strcmp("js_on5", event_name) == 0) {
        cef_browser_t *browser = g_browseer->get_browser(g_browseer);
        _ipc_main_send(browser, "call_js5", NULL, 0);
    }

    // 返回多个参数
    IPC_Value *response = _create_ipc_value_list();

    IPC_Value *response1 = _create_ipc_value_int(100);
    IPC_Value *response2 = _create_ipc_value_string("hello world");

    _list_add_element(response, response1);
    _list_add_element(response, response2);

    return response;
    return NULL;
}

int main(int argc, char *argv[]) {
    int hash = hash_api();
    if (!hash) {
        return 0;
    }

    // EnableHighDpiSupport();

    // 初始化主参数
    void *args = init_main_args(argc, argv);

    browser_app *browser = NULL;
    renderer_app *renderer = NULL;
    other_app *other = NULL;
    cef_app_t *app_t = NULL;

    // 初始化命令行参数，获取进程类型
    cef_command_line_t *command_line = command_line_create();
    command_line_init(command_line, argc, argv);

    int process_type = command_line_process_type(command_line);
    if (process_type == 0) {
        // 初始化browser app
        browser = browser_app_create();
        app_t = &browser->cef_app;
    } else if (process_type == 1) {
        // printf("render process ------------------------------------------+++++++++++++++++++++++++++");
        renderer = renderer_app_create();
        app_t = &renderer->cef_app;
    } else {
        // printf("other process ------------------------------------------+++++++++++++++++++++++++++++");
        other = other_app_create();
        app_t = &other->cef_app;
    }

    // 执行子进程， 主进程启动后，执行到此方法时，此方法会立即返回 -1
    int exit_code = execute_process(args, app_t, NULL);
    LOG_DEBUG("execute_process code %d\n", exit_code);
    if (exit_code >= 0) {
        free(args);
        return exit_code;
    }

    // 初始化cef 设置
    cef_settings_t *settings = init_settings_t();

    // 初始化cef
    int res = initialize_cef(args, settings, &browser->cef_app, NULL);
    if (res == 0) {
        LOG_ERROR("initialize_cef faild\n");
        return 0;
    }

    // 初始化browser_settings
    cef_browser_settings_t *browser_settings = init_browser_settings();

    LOG_DEBUG("cef_window_t create success-----------------");
    browser_view_delegate *view_delegate;
    page_handler *page;
    cef_browser_view_t *browser_view;

    view_delegate = create_browser_view_delegate(800, 600, "icon/icon1.png", "popup window", 0);
    LOG_DEBUG("view_delegate create success-----------------\n");
    page = create_page_handler();

    browser_view = browser_view_create(page, "html/index.html", browser_settings, NULL, NULL, view_delegate);
    g_browseer = browser_view;
    LOG_DEBUG("browser_view ref count-----------------%d\n",
              browser_view->base.base.has_at_least_one_ref(&browser_view->base.base));
    // window_delegate_ref_t *window_delegate = create_window_delegate_ref(browser_view, -1, -1, 800, 600);
    // window_delegate->ref_count.add_ref(&window_delegate->ref_count);
    // cef_window_t *window = window_create_top_level(&window_delegate->cef_window_delegate);
    // printf("browser_view create success-----------------\n");
    // window->base.add_child_view(&window->base, &browser_view->base);
    window_delegate *window_delegate_ptr =
        create_window_delegate(browser_view, 800, 600, "icon/icon1.png", "cef_c_wrapper", 0, 0);

    // 创建窗口
    cef_window_t *window = create_window(window_delegate_ptr);

    // 加载url
    // load_url(browser_view, "http://www.baidu.com");

    // 注册 进程消息处理器
    _set_main_process_message_handeler(on_main_process_message_handler_impl);

    run_message_loop();

    LOG_DEBUG("log: shutdown_cef11...................\n");

    // 清理资源
    // free(args);
    // free(settings);
    // free(browser);
    // free(renderer);
    // free(other);
    // window->base.base.base.release(&window->base.base.base);
    // browser_view->base.base.release(&browser_view->base.base);
    // free(view_delegate);
    // free(page);
    // free(command_line);

    shutdown_cef();
    return 0;
}
